- Published on
Chat Bot 实战
- Authors

- Name
- 游戏人生
实现步骤
- 首先定义一个简单的,根据 MBTI 类型和问题回答用户的 chain:
const prompt = ChatPromptTemplate.fromMessages([
[
"system",
"你是一个共情能力非常强的心理医生,并且很了解MBTI(迈尔斯-布里格斯性格类型指标)的各种人格类型,你的任务是根据来访者的 MBTI 和问题,给出针对性的情感支持,你的回答要富有感情、有深度和充足的情感支持,引导来访者乐观积极面对问题",
],
["human", "用户的 MBTI 类型是{type}, 这个类型的特点是{info}, 他的问题是{question}"],
]);
const llm = new ChatAlibabaTongyi({
model: "qwen-max",
});
const mbtiChain = RunnableSequence.from([prompt, model, new StringOutputParser()]);
这是非常简单的 chat chain,除了告诉 llm MBTI 相关的信息外,还给 llm 设定了 “引导来访者乐观积极面对问题” 这样有倾向性的 prompt,引导 prompt 的回答风格。
需要的参数:
- type: 用户的 MBTI 类型
- info: 对应 MBTI 的类型的特点描述。对于这种由固定答案的信息,不要让 llm 自己生成,而且由我们提供确定性的信息。
- question: 用户的问题
- 据此定义一个自定义的 tool:
const mbtiTool = new DynamicStructuredTool({
name: "get-mbti-chat",
schema: z.object({
type: z.enum(mbtiList).describe("用户的 MBTI 类型"),
question: z.string().describe("用户的问题"),
}),
func: async ({ type, question }) => {
const info = mbtiInfo[type];
const res = await mbtiChain.invoke({ type, question, info });
return res;
},
description: "根据用户的问题和 MBTI 类型,回答用户的问题",
});
其中,mbtiList 是穷举所有 MBTI 的类型。 mbtiInfo 是从外部 json 中加载出来的,以 mbti 类型为 key 对性格描述的 object。 这里把 type 和 question 定义为我们函数 schema 的必填的参数,方便 llm 对函数的理解。
- 据此创建一个 agents:
const tools = [mbtiTool];
const agentPrompt = await ChatPromptTemplate.fromMessages([
[
"system",
"你是一个用户接待的 agent,通过自然语言询问用户的 MBTI 类型和问题,直到你有足够的信息调用 get-mbti-chat 来回答用户的问题",
],
new MessagesPlaceholder("history_message"),
["human", "{input}"],
new MessagesPlaceholder("agent_scratchpad"),
]);
const llm = new ChatAlibabaTongyi({
model: "qwen-max",
temperature: 0.4,
});
const agent = await createOpenAIToolsAgent({
llm,
tools,
prompt: agentPrompt,
});
const agentExecutor = new AgentExecutor({
agent,
tools,
});
为了演示,只给 agents 添加了这一个 tool,并且在 system prompt 中强化了对 get-mbti-chat 的调用的指示。如果是在工程中,也不要加太多的 tool,可以采用 Route/RunnableBranch 等方案,由路由去引导用户到对应的专业 agents 去处理。
- 给 agents 添加 history:(也可以使用持久化在文件中的 chat history 解决方案)
const messageHistory = new ChatMessageHistory();
const agentWithChatHistory = new RunnableWithMessageHistory({
runnable: agentExecutor,
getMessageHistory: () => messageHistory,
inputMessagesKey: "input",
historyMessagesKey: "history_message",
});
- 使用 nodejs 的 readline 内置库,迅速构建一个可以在 cli 中使用的 chat bot,方便进行测试:
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
function chat() {
rl.question("User: ", async (input) => {
if (input.toLowerCase() === "exit") {
rl.close();
return;
}
const response = await agentWithChatHistory.invoke(
{
input,
},
{
configurable: {
sessionId: "no-used",
},
}
);
console.log("Agent: ", response.output);
chat();
});
}
console.log("请输入问题。 输入 exit 退出聊天。");
chat();
6.运行脚本,测试 chat bot。